package com.aplink.generic.xmlparser;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.aplink.generic.constant.ConfigParameter;
import com.aplink.generic.constant.ObjProConstant;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.TableInfo;

public class TableInfoParser {
	private static String getTextNodeValue(final Node node) {
		Node child;
		if (node != null) {
			if (node.hasChildNodes()) {
				child = node.getFirstChild();
				while (child != null) {
					if (child.getNodeType() == Node.TEXT_NODE) {
						return child.getNodeValue();
					}
					child = child.getNextSibling();
				}
			}
		}
		return "";
	}

	public static ArrayList<TableInfo> parse(final Document doc) {
		final ArrayList<TableInfo> tableInfoList = new ArrayList<TableInfo>();
		final NodeList nList = doc
		        .getElementsByTagName(ConfigParameter.TABLE_STRUCTURE);
		for (int temp = 0; temp < nList.getLength(); temp++) {
			final TableInfo tableInfo = new TableInfo();
			final StringBuilder createTableQuery = new StringBuilder();
			final Node nNode = nList.item(temp);
			String tableId = "";
			// set tableInfo ID
			if (nNode.hasAttributes()) {
				final Attr attr = (Attr) nNode.getAttributes().getNamedItem(
				        ConfigParameter.TABLE_ID);
				if (attr != null) {
					tableId = attr.getNodeValue();
					tableInfo.setTableName(tableId);
					createTableQuery.append("CREATE TABLE " + tableId + " ( ");
				}
			}
			// set obj_prop tags
			if (nNode.getNodeType() == Node.ELEMENT_NODE) {
				final Element element = (Element) nNode;
				// get Obj_prop tags of this node
				final NodeList ObjPropNodes = element
				        .getElementsByTagName(ConfigParameter.TABLE_OBJ_PROP);
				for (int objIndex = 0; objIndex < ObjPropNodes.getLength(); objIndex++) {
					final Node nObjPropNode = ObjPropNodes.item(objIndex);
					final ObjPropInfo objPropInfo = new ObjPropInfo();
					if (nObjPropNode.getNodeType() == Node.ELEMENT_NODE) {

						final Element elementObjPropNode = (Element) nObjPropNode;
						if (elementObjPropNode.hasAttributes()) {
							final String defaultValue = XmlPaserUtil
							        .getAttrValue(nObjPropNode,
							                ObjProConstant.OBJ_DEFAULT_VALUE);
							if (defaultValue != null) {
								objPropInfo.setDefaultValue(defaultValue);
							}
						}
						String content = "";
						String objClass = "";
						// get ID of this property
						NodeList nodes = elementObjPropNode
						        .getElementsByTagName(ObjProConstant.OBJ_CLASS_ID);
						if (nodes.getLength() != 0) {
							content = TableInfoParser.getTextNodeValue(nodes
							        .item(0));
							objPropInfo.setTableName(content); // done
							objClass = content;
						}

						// get ID of this property
						nodes = elementObjPropNode
						        .getElementsByTagName(ObjProConstant.OBJ_PROP_ID);
						if (nodes.getLength() != 0) {
							content = TableInfoParser.getTextNodeValue(nodes
							        .item(0));
							objPropInfo.setColumnName(content); // done
						}

						// check isKey
						final Node nNodeID = nodes.item(0);
						final Element elementchild = (Element) nNodeID;
						final String iskey = elementchild
						        .getAttribute(ObjProConstant.OBJ_PROP_ISKEY);
						if (iskey.compareToIgnoreCase("Y") == 0) {
							objPropInfo.setKey(true); // done
						}

						// check isAuto
						final String isAuto = elementchild
						        .getAttribute(ObjProConstant.OBJ_PROP_ISAUTO);
						if (isAuto.compareToIgnoreCase("Y") == 0) {
							objPropInfo.setIsAuto(true); // done
						}

						// get datatype of this property
						nodes = elementObjPropNode
						        .getElementsByTagName(ObjProConstant.OBJ_PROP_DATATYPE);
						if (nodes.getLength() != 0) {
							content = TableInfoParser.getTextNodeValue(nodes
							        .item(0));
							objPropInfo.setDataType(content); // done
						}

						// we add this objPropInfo into objPropInfoList
						if (objClass.equalsIgnoreCase(tableId)) {
							createTableQuery.append(objPropInfo.getColumnName()
							        + " ");
							createTableQuery.append(objPropInfo.getDataType()
							        .getValue());
							if (objPropInfo.isKey()) {
								createTableQuery.append(" PRIMARY KEY ");
								if (objPropInfo.isAuto()) {
									createTableQuery
									        .append(" AUTOINCREMENT NOT NULL");
								}
							} else {
								if (objPropInfo.getDefaultValue() != null) {
									createTableQuery.append(" DEFAULT "
									        + objPropInfo.getDefaultValue());
								}
							}
							if (objIndex < (ObjPropNodes.getLength() - 1)) {
								createTableQuery.append(" , ");
							}
							tableInfo.addColumList(objPropInfo);
						}
					}

				}
			}
			// add this tableInfo into tableInfoList
			createTableQuery.append(" );");
			tableInfo.setCreateTableQuery(createTableQuery.toString());
			tableInfoList.add(tableInfo);
		}
		return tableInfoList;
	}

	public static ArrayList<TableInfo> parserTableStructure(final int xmlFileId) {
		try {
			final Document document = XmlPaserUtil.openDocumentFrom(xmlFileId);
			return TableInfoParser.parse(document);
		} catch (final ParserConfigurationException e) {
			e.printStackTrace();
		} catch (final SAXException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
